using System;
using System.Collections;
using System.Data;
using System.Data.Common;
using System.Collections.Generic;

using WHC.Pager.Entity;
using Microsoft.Practices.EnterpriseLibrary.Data;
using WHC.Hotel.Entity;
using WHC.Hotel.IDAL;
using WHC.OrderWater.Commons;

namespace WHC.Hotel.DAL
{
	/// <summary>
	/// Order 的摘要说明。
	/// </summary>
	public class Order : BaseDAL<OrderInfo>, IOrder
	{
		#region 对象实例及构造函数

		public static Order Instance
		{
			get
			{
				return new Order();
			}
		}
		public Order() : base("KF_Order","ID")
		{
		}

		#endregion

		/// <summary>
		/// 将DataReader的属性值转化为实体类的属性值，返回实体类
		/// </summary>
		/// <param name="dr">有效的DataReader对象</param>
		/// <returns>实体类对象</returns>
		protected override OrderInfo DataReaderToEntity(IDataReader dataReader)
		{
			OrderInfo orderInfo = new OrderInfo();
			SmartDataReader reader = new SmartDataReader(dataReader);
			
			orderInfo.ID = reader.GetInt32("ID");
			orderInfo.OrderNo = reader.GetString("OrderNo");
			orderInfo.RoomNo = reader.GetString("RoomNo");
			orderInfo.RoomType = reader.GetString("RoomType");
			orderInfo.OriginalPrice = reader.GetDecimal("OriginalPrice");
			orderInfo.DiscountRate = reader.GetDouble("DiscountRate");
			orderInfo.DiscountPrice = reader.GetDecimal("DiscountPrice");
			orderInfo.IsPartTime = reader.GetBoolean("IsPartTime");
			orderInfo.Customer_ID = reader.GetInt32("Customer_ID");
			orderInfo.CustomerName = reader.GetString("CustomerName");
			orderInfo.IDNumber = reader.GetString("IDNumber");
			orderInfo.PreLivedDays = reader.GetInt32("PreLivedDays");
			orderInfo.Persons = reader.GetInt32("Persons");
			orderInfo.DepositMoney = reader.GetDecimal("DepositMoney");
			orderInfo.PayType = reader.GetString("PayType");
			orderInfo.Note = reader.GetString("Note");
			orderInfo.Createor = reader.GetString("Createor");
			orderInfo.CreateDate = reader.GetDateTime("CreateDate");
            orderInfo.IsCheckOut = reader.GetBoolean("IsCheckOut");
            orderInfo.CheckOutDate = reader.GetDateTime("CheckOutDate");
            orderInfo.BillNumber = reader.GetString("BillNumber");
            orderInfo.MasterRoomNo = reader.GetString("MasterRoomNo");
			orderInfo.IsContractOrder = reader.GetBoolean("IsContractOrder");
			orderInfo.ContractUnit = reader.GetString("ContractUnit");
			orderInfo.ContractPrice = reader.GetDecimal("ContractPrice");
			orderInfo.ContractStatus = reader.GetString("ContractStatus");
			orderInfo.ContractPreOff = reader.GetDateTime("ContractPreOff");
            orderInfo.IsEachPay = reader.GetBoolean("IsEachPay");
            orderInfo.PreOffDate = reader.GetDateTime("PreOffDate");
            orderInfo.IsSecret = reader.GetBoolean("IsSecret");
            orderInfo.IsprotocolUnit = reader.GetBoolean("IsprotocolUnit");
            orderInfo.ProtocolUnitId = reader.GetInt32("ProtocolUnitId");
            orderInfo.ProtocolUnit = reader.GetString("ProtocolUnit");
            orderInfo.CreditCardMax = reader.GetDecimal("CreditCardMax");
            orderInfo.CreditCardNum = reader.GetString("CreditCardNum");
            orderInfo.PreGrantNum = reader.GetString("PreGrantNum");
            orderInfo.CheckType = reader.GetInt32("CheckType");
            orderInfo.TeamName = reader.GetString("TeamName");
            orderInfo.IsVirtualAccount = reader.GetInt32("IsVirtualAccount");
            orderInfo.AuditDate = reader.GetDateTime("AuditDate");
            orderInfo.IsAudit = reader.GetInt32("IsAudit");
			
			return orderInfo;
		}

		/// <summary>
		/// 将实体对象的属性值转化为Hashtable对应的键值
		/// </summary>
		/// <param name="obj">有效的实体对象</param>
		/// <returns>包含键值映射的Hashtable</returns>
        protected override Hashtable GetHashByEntity(OrderInfo obj)
		{
		    OrderInfo info = obj as OrderInfo;
			Hashtable hash = new Hashtable(); 
			
 			hash.Add("OrderNo", info.OrderNo);
 			hash.Add("RoomNo", info.RoomNo);
 			hash.Add("RoomType", info.RoomType);
 			hash.Add("OriginalPrice", info.OriginalPrice);
 			hash.Add("DiscountRate", info.DiscountRate);
 			hash.Add("DiscountPrice", info.DiscountPrice);
 			hash.Add("IsPartTime", info.IsPartTime);
 			hash.Add("Customer_ID", info.Customer_ID);
 			hash.Add("CustomerName", info.CustomerName);
 			hash.Add("IDNumber", info.IDNumber);
 			hash.Add("PreLivedDays", info.PreLivedDays);
 			hash.Add("Persons", info.Persons);
 			hash.Add("DepositMoney", info.DepositMoney);
 			hash.Add("PayType", info.PayType);
 			hash.Add("Note", info.Note);
 			hash.Add("Createor", info.Createor);
 			hash.Add("CreateDate", info.CreateDate);
            hash.Add("IsCheckOut", info.IsCheckOut);//该字段独立更新
            //hash.Add("CheckOutDate", info.CheckOutDate);//该字段独立更新
            hash.Add("BillNumber", info.BillNumber);//该字段独立更新
            hash.Add("MasterRoomNo", info.MasterRoomNo);
 			hash.Add("IsContractOrder", info.IsContractOrder);
 			hash.Add("ContractUnit", info.ContractUnit);
 			hash.Add("ContractPrice", info.ContractPrice);
 			hash.Add("ContractStatus", info.ContractStatus);
 			hash.Add("ContractPreOff", info.ContractPreOff);
            hash.Add("IsEachPay", info.IsEachPay);
            hash.Add("PreOffDate", info.PreOffDate);
            hash.Add("IsSecret", info.IsSecret);
            hash.Add("IsprotocolUnit", info.IsprotocolUnit);
            hash.Add("ProtocolUnit", info.ProtocolUnit);
            hash.Add("ProtocolUnitId", info.ProtocolUnitId);
            hash.Add("PreGrantNum", info.PreGrantNum);
            hash.Add("CreditCardNum", info.CreditCardNum);
            hash.Add("CreditCardMax", info.CreditCardMax);
            hash.Add("CheckType", info.CheckType);
            hash.Add("TeamName", info.TeamName);
            hash.Add("IsVirtualAccount", info.IsVirtualAccount);
            hash.Add("IsAudit", info.IsAudit);
            hash.Add("AuditDate", info.AuditDate);
				
			return hash;
		}

        /// <summary>
        /// 获取当前入住房间的订单信息
        /// </summary>
        /// <param name="roomNo"></param>
        /// <returns></returns>
        public OrderInfo GetCurrentOrder(string roomNo)
        {
            string condition = string.Format("RoomNo='{0}' and IsCheckOut=0 ", roomNo);
            return this.FindSingle(condition);
        }

        /// <summary>
        /// 获取结账单相关的所有订单ID信息
        /// </summary>
        /// <returns></returns>
        public List<int> GetRelatedOrderID(string billNumber)
        {
            string sql = string.Format(@"Select distinct ID from {0} where BillNumber='{1}' and IsCheckOut=1 ", tableName, billNumber);
            List<int> list = new List<int>();

            Database db = DatabaseFactory.CreateDatabase();
            DbCommand command = db.GetSqlStringCommand(sql);
            using (IDataReader dr = db.ExecuteReader(command))
            {
                while (dr.Read())
                {
                    int id = Convert.ToInt32(dr["ID"].ToString());
                    list.Add(id);
                }
            }
            return list;
        }
                 
        /// <summary>
        /// 获取一条订单的所有订单信息
        /// </summary>
        /// <param name="roomNo">可以是主房间号，也可以是副房间号</param>
        /// <returns></returns>
        public List<OrderInfo> GetRelatedOrders(string roomNo)
        {
            string sql = string.Format(@"Select * from {0} Where (IsCheckOut = 0) AND MasterRoomNo in 
                                        (select MasterRoomNo from {0} 
                                        where RoomNo='{1}' and IsCheckOut=0) ", tableName, roomNo);
            OrderInfo entity = null;
            List<OrderInfo> list = new List<OrderInfo>();

            Database db = DatabaseFactory.CreateDatabase();
            DbCommand command = db.GetSqlStringCommand(sql);
            using (IDataReader dr = db.ExecuteReader(command))
            {
                while (dr.Read())
                {
                    entity = DataReaderToEntity(dr);
                    list.Add(entity);
                }
            }
            return list;
        }

        /// <summary>
        /// 更新当前未结帐的原有的主房间为新的主房间号
        /// </summary>
        /// <param name="oldMasterRoomNo"></param>
        /// <param name="newMasterRoomNo"></param>
        public void SetRelatedOrderMasterRoom(string oldMasterRoomNo, string newMasterRoomNo)
        {
            string sql = string.Format(@"Update {0} set MasterRoomNo ='{1}' Where (IsCheckOut = 0) AND MasterRoomNo='{2}'", 
                                        tableName, newMasterRoomNo, oldMasterRoomNo);

            Database db = DatabaseFactory.CreateDatabase();
            DbCommand command = db.GetSqlStringCommand(sql);
            db.ExecuteNonQuery(command);
        }
               
        /// <summary>
        /// 获取主从房间的相关房间
        /// </summary>
        /// <param name="roomNo">可以是主房间号，也可以是副房间号</param>
        /// <returns></returns>
        public List<string> GetRelatedRooms(string roomNo)
        {
            string sql = string.Format(@"Select RoomNo from {0} Where (IsCheckOut = 0) AND MasterRoomNo in 
                                        (select MasterRoomNo from {0} 
                                        where RoomNo='{1}' and IsCheckOut=0) ", tableName, roomNo);
            List<string> list = new List<string>();

            Database db = DatabaseFactory.CreateDatabase();
            DbCommand command = db.GetSqlStringCommand(sql);
            using (IDataReader dr = db.ExecuteReader(command))
            {
                while (dr.Read())
                {
                    list.Add(dr["RoomNo"].ToString());
                }
            }
            return list;
        }

        /// <summary>
        /// 更新订单的结账状态和时间
        /// </summary>
        /// <param name="Id">订单ID</param>
        /// <param name="isCheckOut">是否结账</param>
        /// <param name="checkOutDate">结账时间</param>
        /// <param name="billNumber">账单号</param>
        /// <returns></returns>
        public bool UpdateCheckOut(int Id, bool isCheckOut, DateTime checkOutDate, string billNumber)
        {
            string sql = string.Format(@"Update {0} set IsCheckOut={1}, CheckOutDate='{2}', 
                                                         ContractStatus='离店' Where ID={3}",
                this.tableName, isCheckOut ? "1" : "0", checkOutDate, Id);

            Database db = DatabaseFactory.CreateDatabase();
            DbCommand command = db.GetSqlStringCommand(sql);
            return db.ExecuteNonQuery(command) > 0;
        }


        /// <summary>
        /// 更新订单的结账状态和时间
        /// </summary>
        /// <param name="mainRoomNo">主房间</param>
        /// <param name="isCheckOut">是否结账</param>
        /// <param name="checkOutDate">结账时间</param>
        /// <param name="billNumber">账单号</param>
        /// <returns></returns>
        public bool UpdateCheckOutByMasterRoomNo(string mainRoomNo, bool isCheckOut, DateTime checkOutDate, string billNumber)
        {
            string sql = string.Format(@"Update {0} set IsCheckOut={1}, CheckOutDate='{2}', 
                                                         ContractStatus='离店' Where MasterRoomNo='{3}'",
                this.tableName, isCheckOut ? "1" : "0", checkOutDate, mainRoomNo);

            Database db = DatabaseFactory.CreateDatabase();
            DbCommand command = db.GetSqlStringCommand(sql);
            return db.ExecuteNonQuery(command) > 0;
        }


        /// <summary>
        /// 更新夜审状态
        /// </summary>
        /// <param name="Id">订单ID</param>
        /// <param name="isCheckOut">是否结账</param>
        /// <param name="checkOutDate">结账时间</param>
        /// <returns></returns>
        public bool UpdateAuditStatus(int Id, DateTime AuditDate)
        {
            string sql = string.Format(@"Update {0} set IsAudit={1}, AuditDate='{2}' Where ID={3}",
                 this.tableName, "1", AuditDate, Id);

            Database db = DatabaseFactory.CreateDatabase();
            DbCommand command = db.GetSqlStringCommand(sql);
            return db.ExecuteNonQuery(command) > 0;
        }

    }
}